home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World of Computer Software
/
The World of Computer Software.iso
/
vsc92nov.zip
/
Symbol.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-11-02
|
4KB
|
185 lines
/*
* Symbol.c -- Implementation of Scheme Symbols
*
* (C) m.b (Matthias Blume), Mar 1992, HUB/Ger
*/
# ident "@(#)Symbol.c (C) M.Blume, Humboldt-Uni Berlin, 1.2"
# include <stdio.h>
# include <string.h>
# include <ctype.h>
# include "storext.h"
# include "Symbol.h"
# include "Primitive.h"
# include "identifier.h"
# include "type.h"
# include "except.h"
# define SPECIAL_CHARS " \t\n\r\b\a\v\\\"\',@()."
# define SYMTAB_HASH_SIZE 41
static
ScmSymbol *symbol_table [SYMTAB_HASH_SIZE];
static
size_t size_hook (void *vsym)
{
return (sizeof (ScmSymbol) + ((ScmSymbol *)vsym)->length - 1);
}
static
void apply_to_subs (void *vsym, applied_proc proc, void *cd)
{
ScmSymbol *sym = (ScmSymbol *) vsym;
(*proc) ((void *)&sym->hashlink, cd);
(*proc) ((void *)&sym->value, cd);
(*proc) ((void *)&sym->properties, cd);
}
static
void dump (void *vsym, FILE *file)
{
ScmSymbol *sym = (ScmSymbol *) vsym;
unsigned i;
dump_ul (sym->length, file);
for (i = 0; i < sym->length; i++)
putc (sym->array[i], file);
}
static
void *restore_init (FILE *file)
{
ScmSymbol *sym;
unsigned i;
unsigned short length;
length = restore_ul (file);
sym = getmem (ScmType (Symbol), sizeof (ScmSymbol) + length - 1);
sym->length = length;
for (i = 0; i < length; i++)
if ((sym->array[i] = getc (file)) == EOF)
fatal ("bad dump file format (Symbol)");
return sym;
}
static
void display (void *vsym, putc_proc pp, void *cd)
{
ScmSymbol *sym = vsym;
unsigned i;
for (i = 0; i < sym->length; i++)
(* pp) (sym->array[i], cd);
}
static
void write_this (void *vsym, putc_proc pp, void *cd)
{
ScmSymbol *sym = vsym;
unsigned i;
int c;
for (i = 0; i < sym->length; i++) {
c = sym->array[i];
if (strchr (SPECIAL_CHARS, c) == NULL)
if (isprint (c))
(* pp) (c, cd);
else {
char buf[16];
sprintf (buf, "\\%03o", (unsigned char)c);
putc_string (buf, pp, cd);
}
else {
(* pp) ('\\', cd);
(* pp) (c, cd);
}
}
}
static
void apply_to_symtab_entries (void *vsymtab, applied_proc proc, void *cd)
{
int i;
ScmSymbol **symtab = vsymtab;
for (i = 0; i < SYMTAB_HASH_SIZE; i++)
(* proc) ((void *)&symtab[i], cd);
}
static
int hash_key (const char *string, unsigned short length)
/* string is not necessarily a C-string (0-terminated), so we need its length */
{
int sum;
sum = 0;
while (length--)
sum += (unsigned char) *string++;
return sum % SYMTAB_HASH_SIZE;
}
void *ScmMakeSymbol (const char *name, unsigned short length)
/* name is not necessarily a C-string (0-terminated), so we need its length */
{
int key = hash_key (name, length);
ScmSymbol *l = symbol_table [key];
while (l != NULL) {
if (length == l->length && memcmp (name, l->array, length) == 0)
break;
l = l->hashlink;
}
if (l == NULL) {
l = getmem (ScmType (Symbol), sizeof (ScmSymbol) + length - 1);
l->hashlink = symbol_table [key];
symbol_table [key] = l;
l->value = l->properties = NULL;
l->length = length;
memcpy (l->array, name, length);
}
return l;
}
void ScmInitSymtab (void)
{
int i;
unsigned long seq_num;
ScmPrimitive *prim;
ScmSymbol *sym;
/* Make an empty hash table */
for (i = 0; i < SYMTAB_HASH_SIZE; i++)
symbol_table [i] = NULL;
/* register symbol_table at storage module */
register_global_object (symbol_table, apply_to_symtab_entries);
for (seq_num = 0; (prim = GetScmPrimitive (seq_num)) != NULL; seq_num++) {
sym = ScmMakeSymbol (prim->name, strlen (prim->name));
sym->value = prim;
}
}
static
struct scheme_od_extension ext = {
display, write_this,
NULL, NULL, /* Symbols must coincide to be equal */
};
OD_VECTOR (ScmSymbol_od_vector,
0,
size_hook,
apply_to_subs,
SYMBOL_IDENTIFIER,
dump, restore_init, NULL,
NULL,
NULL, NULL,
&ext
);